﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;

namespace MEMDB
{
    public class SQLConnection
    {
        public  Socket m_socket;
        private bool m_bConnected;
        private string m_strConnectionString;

        public SQLConnection(string strConnectionString)
        {
            m_strConnectionString = strConnectionString;
            m_bConnected = false;
        }

        public SQLConnection()
        {
            m_bConnected = false;
        }

        public String ConnectString
        {
            set
            {
                this.m_strConnectionString = value;
            }
            get
            {
                return this.m_strConnectionString;
            }
        }

        public bool Connected
        {
            set
            {
                this.m_bConnected = value;
            }
            get
            {
                return this.m_bConnected;
            }
        }
        public bool Login(IPAddress ipAddress, int port, string strLogin, ref String retMsg)
        {
            m_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            IPEndPoint remoteEP = new IPEndPoint(ipAddress, port);
            int tryTimes = 5;
            while (tryTimes > 0)
            {
                --tryTimes;
                try
                {
                    m_socket.Connect(remoteEP);
                    break;
                }
                catch (System.Exception ex)
                {
                    continue;
                }
            }
            if (tryTimes == 0)
            {
                retMsg = "网络连接超时";
                return false;
            }
            String str = "hello";
            byte[] buf = Encoding.Unicode.GetBytes(str);
            m_socket.Send(buf);
            m_socket.Receive(buf);
            String strRet = Encoding.ASCII.GetString(buf);
            strRet = strRet.TrimEnd(new char[]{'\0', '?'});
            if (strRet.Equals(str))
            { 
                // hand shake 成功
            }

            // The login str and the acknowledgement.
            buf = Encoding.Unicode.GetBytes(strLogin);
            m_socket.Send(buf);
            buf = new byte[256];
            m_socket.Receive(buf);
            int error = BitConverter.ToInt32(buf, 0);
            retMsg = Encoding.Unicode.GetString(buf, 8, buf.Length - 8);
            if((error_code)error != error_code.SUCCESS)
            {
                return false;
            }
            m_bConnected = true;
            return true ;
        }

        public bool Open()
        {
            string strIPAddress;
            string strPort;
            string strUser;
            string strPassward;
            string strDatabase;

            int iFirstQuotation, iLastQuotation, iComa;
            m_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            iFirstQuotation = m_strConnectionString.IndexOf('\'');
            if (iFirstQuotation == -1)
                return false;

            iLastQuotation = m_strConnectionString.IndexOf('\'', iFirstQuotation + 1);
            if(iLastQuotation == -1)
                return false;

            iComa = m_strConnectionString.IndexOf(':', iFirstQuotation + 1);
            if(iComa == -1)
                return false;

            strIPAddress = m_strConnectionString.Substring(iFirstQuotation + 1, iComa - iFirstQuotation - 1);
            strPort = m_strConnectionString.Substring(iComa + 1, iLastQuotation - iComa - 1);

            iFirstQuotation = m_strConnectionString.IndexOf('\'', iLastQuotation + 1);
            if (iFirstQuotation == -1)
                return false;

            iLastQuotation = m_strConnectionString.IndexOf('\'', iFirstQuotation + 1);
            if (iLastQuotation == -1)
                return false;

            strUser = m_strConnectionString.Substring(iFirstQuotation + 1, iLastQuotation - iFirstQuotation - 1);

            iFirstQuotation = m_strConnectionString.IndexOf('\'', iLastQuotation + 1);
            if (iFirstQuotation == -1)
                return false;

            iLastQuotation = m_strConnectionString.IndexOf('\'', iFirstQuotation + 1);
            if (iLastQuotation == -1)
                return false;

            strPassward = m_strConnectionString.Substring(iFirstQuotation + 1, iLastQuotation - iFirstQuotation - 1);

            iFirstQuotation = m_strConnectionString.IndexOf('\'', iLastQuotation + 1);
            if (iFirstQuotation == -1)
                return false;

            iLastQuotation = m_strConnectionString.IndexOf('\'', iFirstQuotation + 1);
            if (iLastQuotation == -1)
                return false;

            strDatabase = m_strConnectionString.Substring(iFirstQuotation + 1, iLastQuotation - iFirstQuotation - 1);

            IPAddress ipAddress;
            int port;

            if(!IPAddress.TryParse(strIPAddress, out ipAddress))
            {
                System.Windows.Forms.MessageBox.Show("无效 IP.");
                return false;
            }

            try
            {
                port = Convert.ToInt32(strPort.Trim());
            }
            catch (System.Exception ex)
            {
                System.Windows.Forms.MessageBox.Show("无效端口号." + ex.Message);
                return false;
            }

            IPEndPoint remoteEP = new IPEndPoint(ipAddress, port);
            int tryTimes = 5;
            while (tryTimes > 0)
            {
                --tryTimes;
                try
                {
                    m_socket.Connect(remoteEP);
                    break;
                }
                catch (System.Exception ex)
                {
                    continue;
                }
            }
            if (tryTimes == 0)
            {
                return false;
            }
            String str = "hello";
            byte[] buf = Encoding.Unicode.GetBytes(str);
            m_socket.Send(buf);
            m_socket.Receive(buf);
            String strRet = Encoding.Unicode.GetString(buf);
            if (strRet.Equals(str))
            {
                m_bConnected = true;
                return true;
            }
            return false;
        }

        public void Close()
        {
            m_bConnected = false;
            m_socket.Close();
        }
    }
}